package mines.fila3.letstalk.activities;

import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedList;

import mines.fila3.letstalk.R;
import mines.fila3.letstalk.adapters.MessagesAdapter;
import mines.fila3.letstalk.data.ListMessages;
import mines.fila3.letstalk.params.LetsTalkConst;
import mines.fila3.letstalk.tools.InputStreamConverter;
import mines.fila3.letstalk.tools.LetsTalkNetwork;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.Activity;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.RingtoneManager;
import android.net.ConnectivityManager;
import android.os.AsyncTask;
import android.os.AsyncTask.Status;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.NotificationCompat;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.Toast;

/**
 * The activity to display the list mf messages of this tchat.
 * 
 * @author aminaud & qmahe
 * 
 */
public class ListMessagesActivity extends Activity {

	/**
	 * The listview which display on the view the list of messages.
	 */
	private ListView listViewMessages;

	/**
	 * The object of the asynctask which allows to retrieve the list of
	 * messages.
	 */
	private ListMessagesTask listMessagesTask;

	/**
	 * The progressbar of the view.
	 */
	private ProgressBar progressBar;

	/**
	 * The adapter for the list of messages to define specifically the view
	 * for each message.
	 */
	private MessagesAdapter messagesAdapter;

	/** Boolean for notifications when activity is in background. */
	private boolean shouldNotify = false;

	/**
	 * Boolean for notifications when the activity to send a message is
	 * launched.
	 */
	private boolean sendingMessage = false;

	/** Handler for new messages notification. */
	private final Handler notificationsHandler = new Handler();

	LinkedList<Integer> messagesNotRead;

	Runnable runnable;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_liste_messages);
		findComponents();
	}

	/**
	 * To retrieve components this activity needs from the view.
	 */
	private void findComponents() {
		// we retrieve all components
		listViewMessages = (ListView) findViewById(R.id.listMessages);
		progressBar = (ProgressBar) findViewById(R.id.list_progressbar);

		// we define information for the ListView.
		messagesAdapter = new MessagesAdapter(getApplicationContext());
		listViewMessages.setAdapter(messagesAdapter);
		listViewMessages.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> adapter, View view, int position, long arg) {
				messagesAdapter.setReadMessage(position);
			}
		});
	}

	/**
	 * To retrieve the messages list from a web service.
	 */
	private void retrieveListMessages() {
		// we test if there is an internet connection, if no, we display a
		// message to the user.
		if (LetsTalkNetwork.isConnected((ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE))) {
			// if the AsyncTask is ready, we execute it, else we create
			// it.
			if (listMessagesTask == null || listMessagesTask.getStatus() == Status.FINISHED) {
				listMessagesTask = new ListMessagesTask();
			}
			if (listMessagesTask.getStatus() == Status.PENDING) {
				listMessagesTask.execute();
			}
		} else {
			Toast.makeText(getApplicationContext(), R.string.msg_no_connection, Toast.LENGTH_SHORT).show();
		}
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		outState.putParcelable(LetsTalkConst.KEY_LIST, messagesAdapter.getListMessages());
		String username = getSharedPreferences(LetsTalkConst.USER_CREDENTIALS, MODE_PRIVATE).getString(
				LetsTalkConst.KEY_USERNAME, LetsTalkConst.EMPTY_STRING);
		outState.putString(LetsTalkConst.KEY_USERNAME, username);
		super.onSaveInstanceState(outState);
	}

	@Override
	protected void onRestoreInstanceState(Bundle savedInstanceState) {
		super.onRestoreInstanceState(savedInstanceState);

		// we retrieve the old username and the new one.
		String oldUsername = savedInstanceState.getString(LetsTalkConst.KEY_USERNAME);
		String username = getSharedPreferences(LetsTalkConst.USER_CREDENTIALS, MODE_PRIVATE).getString(
				LetsTalkConst.KEY_USERNAME, LetsTalkConst.EMPTY_STRING);

		if (oldUsername.equals(username)) {
			ListMessages list = (ListMessages) savedInstanceState.getParcelable(LetsTalkConst.KEY_LIST);
			// messagesNotRead = list.getListNoReadMessages();
			if (list != null) {
				messagesAdapter.setListMessages(list);
			}
		}
	}

	@Override
	protected void onStart() {
		super.onStart();
	}

	@Override
	protected void onResume() {
		shouldNotify = false;
		sendingMessage = false;
		notificationsHandler.removeCallbacks(runnable);
		retrieveListMessages();
		super.onResume();
	}

	@Override
	protected void onPause() {
		final long waitTime = 60000;
		shouldNotify = !sendingMessage;
		runnable = new Runnable() {
			@Override
			public void run() {
				if (shouldNotify) {
					retrieveListMessages();
				}
				notificationsHandler.postDelayed(this, waitTime);
			}
		};
		notificationsHandler.postDelayed(runnable, waitTime);
		super.onPause();
	}

	@Override
	protected void onStop() {
		super.onStop();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu items for use in the action bar
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.listmessages_activity_actions, menu);
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle presses on the action bar items
		switch (item.getItemId()) {
		case R.id.action_sendMessage:
			openSendMessage();
			return true;
		case R.id.action_refresh:
			retrieveListMessages();
			return true;
		default:
			return super.onOptionsItemSelected(item);
		}
	}

	/**
	 * To start the activity to send a message.
	 */
	private void openSendMessage() {
		sendingMessage = false;
		Intent intent = new Intent(getApplicationContext(), EnvoyerMessageActivity.class);
		startActivity(intent);
	}

	/**
	 * The AsyncTask to retrieve the message list using the webservice.
	 * 
	 * @author aminaud & qmahe
	 * 
	 */
	private class ListMessagesTask extends AsyncTask<String, Void, String> {

		@Override
		protected void onPreExecute() {
			progressBar.setVisibility(View.VISIBLE);
		}

		@Override
		protected String doInBackground(String... params) {

			String result;

			SharedPreferences prefs = getSharedPreferences(LetsTalkConst.USER_CREDENTIALS, MODE_PRIVATE);
			String username = prefs.getString(LetsTalkConst.KEY_USERNAME, LetsTalkConst.EMPTY_STRING);
			String password = prefs.getString(LetsTalkConst.KEY_PASSWORD, LetsTalkConst.EMPTY_STRING);

			// appeler webservice
			try {
				DefaultHttpClient client = new DefaultHttpClient();
				HttpGet request = new HttpGet(LetsTalkConst.getAdressHTTP(LetsTalkConst.QUERY_LIST, username,
						password));
				HttpResponse response = client.execute(request);
				InputStream content = response.getEntity().getContent();
				result = InputStreamConverter.convertToString(content);
				return result;
			} catch (ClientProtocolException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}

			return null;
		}

		@Override
		protected void onPostExecute(String result) {
			progressBar.setVisibility(View.INVISIBLE);

			if (result != null && !result.isEmpty()) {
				updateList(result.split(LetsTalkConst.MSG_SEPARATOR));
			} else {
				// probleme, on laisse la liste comme elle est.
				Toast.makeText(getApplicationContext(), R.string.msg_problem, Toast.LENGTH_SHORT).show();
			}

		}
	}

	/**
	 * Updates the list of messages.
	 * 
	 * @param content
	 *              An array of messages.
	 */
	private void updateList(String[] content) {
		boolean notify = messagesAdapter.updateData(content);
		// scroll au dernier item
		listViewMessages.setSelection(content.length - 1);
		if (notify && shouldNotify) {
			notifyUser();
		}
	}

	/**
	 * Notifies a user when there are new messages.
	 */
	private void notifyUser() {
		// Activite a ouvrir au clic sur la notification
		Intent resultIntent = new Intent(this, ListMessagesActivity.class);
		PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0, resultIntent,
				PendingIntent.FLAG_UPDATE_CURRENT);

		// Cree la notification
		NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
				.setSmallIcon(R.drawable.ic_launcher).setContentTitle(getString(R.string.msg_notif_title))
				.setContentText(getString(R.string.msg_notif_msgnotread))
				.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
				.setContentIntent(resultPendingIntent);

		// Sets an ID for the notification
		int mNotificationId = 001;
		// Gets an instance of the NotificationManager service
		NotificationManager mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
		// Lance la notification
		mNotifyMgr.notify(mNotificationId, mBuilder.build());
	}
}